import {DynamicModule, Module} from "@nestjs/common";
import Redis, {RedisOptions} from "ioredis";
import {RedisService} from "./redis.service";
import {ConfigModule, ConfigService} from "@nestjs/config";

interface AsyncRedisOptions{
    inject?: any[]
    useFactory: (configService:ConfigService) => Promise<RedisOptions> | RedisOptions
}

@Module({
    providers: [RedisService],
    exports: [RedisService]
})
export class RedisModule{
    static forRoot(options: RedisOptions):DynamicModule{
        const redisClient = new Redis(options)
        return {
            module: RedisModule,
            providers: [
                {
                    provide: "REDIS_CLIENT",
                    useValue: redisClient
                },
                RedisService
            ],
            exports: [RedisService]
        }
    }

    static forRootAsync(options:AsyncRedisOptions):DynamicModule{
        const redisProvider = {
            provide: "REDIS_CLIENT",
            useFactory: async (configService:ConfigService) => {
                const redisOptions = await options.useFactory(configService)
                return new Redis(redisOptions)
            },
            inject: options.inject || [ConfigService]
        }
        return {
            module: RedisModule,
            imports: [ConfigModule],
            providers: [redisProvider,RedisService],
            exports: [redisProvider,RedisService]
        }
    }
}
